using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Xml;

namespace Fornax020.Configuration
{
    /// <summary>
    /// @file ApplicationConfiguration.cs
    /// @brief 应用程序配置管理类
    /// @details 统一管理应用程序的所有配置参数，避免硬编码
    /// 
    /// 设计模式应用：
    /// 1. 单例模式：确保配置的唯一性
    /// 2. 策略模式：可扩展的配置加载策略
    /// 3. 工厂模式：创建不同类型的配置对象
    /// 
    /// @author Fornax020 Development Team
    /// @date 2024
    /// @version 1.0.0
    /// </summary>
    public sealed class ApplicationConfiguration
    {
        #region 单例模式实现
        private static readonly Lazy<ApplicationConfiguration> _instance = 
            new Lazy<ApplicationConfiguration>(() => new ApplicationConfiguration());
        
        /// <summary>
        /// @brief 获取配置实例
        /// @details 单例模式，确保全局只有一个配置实例
        /// @return 配置实例
        /// </summary>
        public static ApplicationConfiguration Instance => _instance.Value;
        
        /// <summary>
        /// @brief 私有构造函数
        /// @details 防止外部实例化，确保单例模式
        /// </summary>
        private ApplicationConfiguration()
        {
            LoadConfiguration();
        }
        #endregion

        #region 串口通信配置
        /// <summary>
        /// @brief 默认串口参数
        /// @details 串口通信的默认配置参数
        /// </summary>
        public class SerialPortConfig
        {
            /// <summary>
            /// 默认波特率
            /// </summary>
            public const int DEFAULT_BAUD_RATE = 9600;
            
            /// <summary>
            /// 默认数据位
            /// </summary>
            public const int DEFAULT_DATA_BITS = 8;
            
            /// <summary>
            /// 默认停止位
            /// </summary>
            public const int DEFAULT_STOP_BITS = 1;
            
            /// <summary>
            /// 默认读取超时时间（毫秒）
            /// </summary>
            public const int DEFAULT_READ_TIMEOUT = 1000;
            
            /// <summary>
            /// 默认写入超时时间（毫秒）
            /// </summary>
            public const int DEFAULT_WRITE_TIMEOUT = 1000;
            
            /// <summary>
            /// 支持的波特率列表
            /// </summary>
            public static readonly int[] SUPPORTED_BAUD_RATES = { 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 };
        }
        #endregion

        #region 设备参数配置
        /// <summary>
        /// @brief X射线设备参数配置
        /// @details 设备操作的限制参数
        /// </summary>
        public class DeviceConfig
        {
            /// <summary>
            /// 最大KV值
            /// </summary>
            public const double MAX_KV_VALUE = 100.0;
            
            /// <summary>
            /// 最小KV值
            /// </summary>
            public const double MIN_KV_VALUE = 0.0;
            
            /// <summary>
            /// 最大MA值
            /// </summary>
            public const double MAX_MA_VALUE = 500.0;
            
            /// <summary>
            /// 最小MA值
            /// </summary>
            public const double MIN_MA_VALUE = 0.0;
            
            /// <summary>
            /// 默认KV值
            /// </summary>
            public const double DEFAULT_KV_VALUE = 10.0;
            
            /// <summary>
            /// 默认MA值
            /// </summary>
            public const double DEFAULT_MA_VALUE = 50.0;
            
            /// <summary>
            /// KV值精度（小数位数）
            /// </summary>
            public const int KV_PRECISION = 1;
            
            /// <summary>
            /// MA值精度（小数位数）
            /// </summary>
            public const int MA_PRECISION = 1;
        }
        #endregion

        #region 监控配置
        /// <summary>
        /// @brief 设备监控配置
        /// @details 定时监控相关参数
        /// </summary>
        public class MonitoringConfig
        {
            /// <summary>
            /// 监控定时器间隔（毫秒）
            /// </summary>
            public const int MONITORING_INTERVAL = 200;
            
            /// <summary>
            /// 监控超时时间（毫秒）
            /// </summary>
            public const int MONITORING_TIMEOUT = 5000;
            
            /// <summary>
            /// 最大重试次数
            /// </summary>
            public const int MAX_RETRY_COUNT = 3;
            
            /// <summary>
            /// 重试间隔（毫秒）
            /// </summary>
            public const int RETRY_INTERVAL = 1000;
        }
        #endregion

        #region UI配置
        /// <summary>
        /// @brief 用户界面配置
        /// @details UI相关的配置参数
        /// </summary>
        public class UIConfig
        {
            /// <summary>
            /// 应用程序标题
            /// </summary>
            public const string APPLICATION_TITLE = "Fornax020 X射线高压发生器控制软件";
            
            /// <summary>
            /// 应用程序版本
            /// </summary>
            public const string APPLICATION_VERSION = "1.0.0";
            
            /// <summary>
            /// 连接状态指示器 - 已连接颜色
            /// </summary>
            public const string CONNECTED_COLOR = "Green";
            
            /// <summary>
            /// 连接状态指示器 - 未连接颜色
            /// </summary>
            public const string DISCONNECTED_COLOR = "Red";
            
            /// <summary>
            /// 曝光状态指示器 - 曝光中颜色
            /// </summary>
            public const string EXPOSING_COLOR = "Yellow";
            
            /// <summary>
            /// 曝光状态指示器 - 未曝光颜色
            /// </summary>
            public const string NOT_EXPOSING_COLOR = "Gray";
            
            /// <summary>
            /// 日志显示最大行数
            /// </summary>
            public const int MAX_LOG_LINES = 1000;
        }
        #endregion

        #region 文件路径配置
        /// <summary>
        /// @brief 文件路径配置
        /// @details 应用程序使用的文件路径
        /// </summary>
        public class PathConfig
        {
            /// <summary>
            /// 日志文件目录 - 程序运行目录下的Logs文件夹
            /// </summary>
            public static readonly string LOG_DIRECTORY = Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, 
                "Logs");
            
            /// <summary>
            /// 配置文件目录 - 程序运行目录下的Config文件夹
            /// </summary>
            public static readonly string CONFIG_DIRECTORY = Path.Combine(
                AppDomain.CurrentDomain.BaseDirectory, 
                "Config");
            
            /// <summary>
            /// 默认日志文件名
            /// </summary>
            public const string DEFAULT_LOG_FILE = "Fornax020";
            
            /// <summary>
            /// 配置文件名称
            /// </summary>
            public const string CONFIG_FILE_NAME = "Fornax020.config";
        }
        #endregion

        #region 错误代码配置
        /// <summary>
        /// @brief 错误代码配置
        /// @details 设备错误代码定义 - 下位机上传的19个故障码
        /// </summary>
        public class ErrorCodeConfig
        {
            #region 设备故障码 (1-19) - 下位机实际发送的错误码
            /// <summary>
            /// KV/MA超限
            /// </summary>
            public const string ERR_KV_MA_OVERLIMIT = "001";
            
            /// <summary>
            /// 阳极MA故障
            /// </summary>
            public const string ERR_ANODEMA_OCCURED = "002";
            
            /// <summary>
            /// 阴极MA故障
            /// </summary>
            public const string ERR_CHAODEMA_OCCURED = "003";
            
            /// <summary>
            /// KV异常
            /// </summary>
            public const string ERR_KVABNORMAL = "004";
            
            /// <summary>
            /// 逆变器过温
            /// </summary>
            public const string ERR_INV_OVERTEMP_FLAG = "005";
            
            /// <summary>
            /// 油温过温
            /// </summary>
            public const string ERR_OIL_OVERTEMP_FLAG = "006";
            
            /// <summary>
            /// 直流母线超限
            /// </summary>
            public const string ERR_DCBUS_OVERLIMIT = "007";
            
            /// <summary>
            /// -15V过压
            /// </summary>
            public const string ERR_N15V_OVERVOLTAGE = "008";
            
            /// <summary>
            /// +15V过压
            /// </summary>
            public const string ERR_P15V_OVERVOLTAGE = "009";
            
            /// <summary>
            /// +24V过压
            /// </summary>
            public const string ERR_P24V_OVERVOLTAGE = "010";
            
            /// <summary>
            /// 灯丝超限
            /// </summary>
            public const string ERR_FIL_OVERLIMIT = "011";
            
            /// <summary>
            /// 打火故障
            /// </summary>
            public const string ERRARCING = "012";
            
            /// <summary>
            /// 联锁故障
            /// </summary>
            public const string ERR_INTERLOCK = "013";
            
            /// <summary>
            /// KV故障
            /// </summary>
            public const string ERR_KV_OCCURED = "014";
            
            /// <summary>
            /// 阴极KV超限
            /// </summary>
            public const string ERR_CATHODEKVOVERLIMIT = "015";
            
            /// <summary>
            /// 阳极超限
            /// </summary>
            public const string ERR_ANTHODEOVERLIMIT = "016";
            
            /// <summary>
            /// KV超限待机
            /// </summary>
            public const string ERR_KVOVERLIMIT_STANDBY = "017";
            
            /// <summary>
            /// 功率超限
            /// </summary>
            public const string ERR_POWER_OVERLIMIT = "018";
            
            /// <summary>
            /// 风扇过流
            /// </summary>
            public const string ERR_FAN_OVERCURRENT = "019";
            #endregion

            /// <summary>
            /// 获取错误描述
            /// </summary>
            /// <param name="errorCode">错误代码</param>
            /// <returns>错误描述</returns>
            public static string GetErrorDescription(string errorCode)
            {
                // 设备故障码 (1-19) - 下位机实际发送的错误码
                if (int.TryParse(errorCode, out int numericCode))
                {
                    switch (numericCode)
                    {
                        case 1:
                            return "KV/MA超限";
                        case 2:
                            return "阳极MA故障";
                        case 3:
                            return "阴极MA故障";
                        case 4:
                            return "KV异常";
                        case 5:
                            return "逆变器过温";
                        case 6:
                            return "油温过温";
                        case 7:
                            return "直流母线超限";
                        case 8:
                            return "-15V过压";
                        case 9:
                            return "+15V过压";
                        case 10:
                            return "+24V过压";
                        case 11:
                            return "灯丝超限";
                        case 12:
                            return "打火故障";
                        case 13:
                            return "联锁故障";
                        case 14:
                            return "KV故障";
                        case 15:
                            return "阴极KV超限";
                        case 16:
                            return "阳极超限";
                        case 17:
                            return "KV超限待机";
                        case 18:
                            return "功率超限";
                        case 19:
                            return "风扇过流";
                        default:
                            break;
                    }
                }

                return $"未知错误: {errorCode}";
            }
        }
        #endregion

        #region 私有字段
        private string _logLevel = "INFO";
        private bool _enableDebugMode = false;
        private bool _autoSaveLog = true;
        private string _lastUsedPortName = "";
        private int _lastUsedBaudRate = SerialPortConfig.DEFAULT_BAUD_RATE;
        #endregion

        #region 公共属性
        /// <summary>
        /// @brief 日志级别
        /// @details 控制日志输出的详细程度
        /// </summary>
        public string LogLevel
        {
            get => _logLevel;
            set => _logLevel = value ?? "INFO";
        }
        
        /// <summary>
        /// @brief 是否启用调试模式
        /// @details 调试模式下会输出更详细的日志信息
        /// </summary>
        public bool EnableDebugMode
        {
            get => _enableDebugMode;
            set => _enableDebugMode = value;
        }
        
        /// <summary>
        /// @brief 是否自动保存日志
        /// @details 控制是否将日志保存到文件
        /// </summary>
        public bool AutoSaveLog
        {
            get => _autoSaveLog;
            set => _autoSaveLog = value;
        }
        
        /// <summary>
        /// @brief 上次使用的串口名称
        /// @details 用于程序启动时自动选择上次使用的串口
        /// </summary>
        public string LastUsedPortName
        {
            get => _lastUsedPortName;
            set => _lastUsedPortName = value ?? "";
        }
        
        /// <summary>
        /// @brief 上次使用的波特率
        /// @details 用于程序启动时自动选择上次使用的波特率
        /// </summary>
        public int LastUsedBaudRate
        {
            get => _lastUsedBaudRate;
            set => _lastUsedBaudRate = value > 0 ? value : SerialPortConfig.DEFAULT_BAUD_RATE;
        }
        #endregion

        #region 私有方法
        /// <summary>
        /// @brief 加载配置
        /// @details 从JSON配置文件或默认值加载配置参数
        /// </summary>
        private void LoadConfiguration()
        {
            try
            {
                // 先尝试从XML配置文件加载
                if (LoadFromXmlConfigFile())
                {
                    System.Diagnostics.Debug.WriteLine("从XML配置文件加载成功");
                    return;
                }
                
                // 如果JSON文件不存在，尝试从app.config加载
                LoadFromConfigFile();
            }
            catch (Exception ex)
            {
                // 如果加载失败，使用默认配置
                System.Diagnostics.Debug.WriteLine($"加载配置文件失败，使用默认配置: {ex.Message}");
                LoadDefaultConfiguration();
            }
        }
        
        /// <summary>
        /// @brief 从XML配置文件加载
        /// @details 从user.config XML文件加载配置参数
        /// </summary>
        private bool LoadFromXmlConfigFile()
        {
            try
            {
                string configFilePath = Path.Combine(PathConfig.CONFIG_DIRECTORY, "user.config");
                
                if (!File.Exists(configFilePath))
                {
                    return false; // XML文件不存在
                }
                
                XmlDocument doc = new XmlDocument();
                doc.Load(configFilePath);
                
                XmlElement root = doc.DocumentElement;
                if (root == null)
                {
                    return false;
                }
                
                // 读取配置项
                _logLevel = GetConfigValue(root, "LogLevel") ?? "INFO";
                _enableDebugMode = bool.TryParse(GetConfigValue(root, "EnableDebugMode"), out bool debugMode) ? debugMode : false;
                _autoSaveLog = bool.TryParse(GetConfigValue(root, "AutoSaveLog"), out bool autoSave) ? autoSave : true;
                _lastUsedPortName = GetConfigValue(root, "LastUsedPortName") ?? "";
                _lastUsedBaudRate = int.TryParse(GetConfigValue(root, "LastUsedBaudRate"), out int baudRate) ? baudRate : SerialPortConfig.DEFAULT_BAUD_RATE;
                
                return true;
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"从XML配置文件加载失败: {ex.Message}");
                return false;
            }
        }
        
        /// <summary>
        /// @brief 获取配置值
        /// @details 从XML元素中获取配置值
        /// </summary>
        private string GetConfigValue(XmlElement root, string name)
        {
            XmlNode node = root.SelectSingleNode(name);
            return node?.InnerText;
        }
        
        /// <summary>
        /// @brief 从配置文件加载
        /// @details 从app.config文件加载配置参数
        /// </summary>
        private void LoadFromConfigFile()
        {
            // 从app.config读取配置
            var logLevel = ConfigurationManager.AppSettings["LogLevel"];
            if (!string.IsNullOrEmpty(logLevel))
            {
                _logLevel = logLevel;
            }
            
            var debugMode = ConfigurationManager.AppSettings["EnableDebugMode"];
            if (bool.TryParse(debugMode, out bool debug))
            {
                _enableDebugMode = debug;
            }
            
            var autoSave = ConfigurationManager.AppSettings["AutoSaveLog"];
            if (bool.TryParse(autoSave, out bool save))
            {
                _autoSaveLog = save;
            }
            
            // 加载串口记忆配置
            var lastPort = ConfigurationManager.AppSettings["LastUsedPortName"];
            if (!string.IsNullOrEmpty(lastPort))
            {
                _lastUsedPortName = lastPort;
            }
            
            var lastBaudRate = ConfigurationManager.AppSettings["LastUsedBaudRate"];
            if (int.TryParse(lastBaudRate, out int baudRate) && baudRate > 0)
            {
                _lastUsedBaudRate = baudRate;
            }
        }
        
        /// <summary>
        /// @brief 加载默认配置
        /// @details 使用默认值初始化配置参数
        /// </summary>
        private void LoadDefaultConfiguration()
        {
            _logLevel = "INFO";
            _enableDebugMode = false;
            _autoSaveLog = true;
            _lastUsedPortName = "";
            _lastUsedBaudRate = SerialPortConfig.DEFAULT_BAUD_RATE;
        }
        #endregion

        #region 公共方法
        /// <summary>
        /// @brief 保存配置
        /// @details 将当前配置保存到XML配置文件
        /// </summary>
        public void SaveConfiguration()
        {
            try
            {
                // 确保配置目录存在
                if (!Directory.Exists(PathConfig.CONFIG_DIRECTORY))
                {
                    Directory.CreateDirectory(PathConfig.CONFIG_DIRECTORY);
                }
                
                // 创建XML文档
                XmlDocument doc = new XmlDocument();
                XmlElement root = doc.CreateElement("Configuration");
                doc.AppendChild(root);
                
                // 添加配置项
                AddConfigElement(doc, root, "LogLevel", _logLevel);
                AddConfigElement(doc, root, "EnableDebugMode", _enableDebugMode.ToString());
                AddConfigElement(doc, root, "AutoSaveLog", _autoSaveLog.ToString());
                AddConfigElement(doc, root, "LastUsedPortName", _lastUsedPortName);
                AddConfigElement(doc, root, "LastUsedBaudRate", _lastUsedBaudRate.ToString());
                
                // 保存到文件
                string configFilePath = Path.Combine(PathConfig.CONFIG_DIRECTORY, "user.config");
                doc.Save(configFilePath);
                
                System.Diagnostics.Debug.WriteLine("配置已保存到XML文件");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"保存配置失败: {ex.Message}");
            }
        }
        
        /// <summary>
        /// @brief 添加配置元素
        /// @details 向XML文档添加配置项
        /// </summary>
        private void AddConfigElement(XmlDocument doc, XmlElement parent, string name, string value)
        {
            XmlElement element = doc.CreateElement(name);
            element.InnerText = value ?? "";
            parent.AppendChild(element);
        }
        
        /// <summary>
        /// @brief 重置为默认配置
        /// @details 将所有配置重置为默认值
        /// </summary>
        public void ResetToDefault()
        {
            LoadDefaultConfiguration();
            SaveConfiguration();
        }
        
        /// <summary>
        /// @brief 保存串口记忆信息
        /// @details 保存上次成功使用的串口信息
        /// @param portName 串口名称
        /// @param baudRate 波特率
        /// </summary>
        public void SaveSerialPortMemory(string portName, int baudRate)
        {
            try
            {
                _lastUsedPortName = portName ?? "";
                _lastUsedBaudRate = baudRate > 0 ? baudRate : SerialPortConfig.DEFAULT_BAUD_RATE;
                
                // 保存到配置文件
                SaveConfiguration();
                
                System.Diagnostics.Debug.WriteLine($"串口记忆信息已保存: {portName}, {baudRate}");
                Console.WriteLine($"串口记忆信息已保存: {portName}, {baudRate}");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine($"保存串口记忆信息失败: {ex.Message}");
                Console.WriteLine($"保存串口记忆信息失败: {ex.Message}");
            }
        }
        
        /// <summary>
        /// @brief 验证配置
        /// @details 验证当前配置的有效性
        /// @return 配置是否有效
        /// </summary>
        public bool ValidateConfiguration()
        {
            try
            {
                // 验证日志级别
                if (string.IsNullOrEmpty(_logLevel))
                {
                    return false;
                }
                
                // 验证文件路径
                if (!Directory.Exists(PathConfig.LOG_DIRECTORY))
                {
                    Directory.CreateDirectory(PathConfig.LOG_DIRECTORY);
                }
                
                return true;
            }
            catch
            {
                return false;
            }
        }
        #endregion
    }
}
